home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / cmdity / yk212src.lha / Yak_2.12_Src / WBStartup / main.c < prev    next >
C/C++ Source or Header  |  1996-01-20  |  15KB  |  561 lines

  1. /*
  2.  * Yak version 2.00
  3.  * ----------------
  4.  * [Yak == Yet Another K(?)ommodity
  5.  *
  6.  * There seems to be a profusion of commodities doing this or that.
  7.  * Heres mine, to do what I want it to:
  8.  *
  9.  *      AutoActivate windows (SunMouse)
  10.  *      ClickToFront, ClickToBack, ScreenCycle
  11.  *      Close/Zip/Shrink/Zoom/Turn a window via keyboard.
  12.  *      Bring up a palette on front screen.
  13.  *      Insert date into read-stream.
  14.  *      Produce key-click (like my keyclick program).
  15.  *      Some other things...
  16.  *
  17.  * Martin W. Scott, Gaël Marziou & Philippe Bastiani, 7/94.
  18.  */
  19.  
  20. #define __USE_SYSBASE 
  21.  
  22. #include <exec/types.h>
  23. #include <exec/libraries.h>
  24. #include <exec/memory.h>
  25. #include <devices/inputevent.h>
  26. #include <dos/dos.h>
  27. #include <dos/dostags.h>
  28. #include <dos/notify.h>
  29. #include <graphics/displayinfo.h>
  30. #include <libraries/commodities.h>
  31. #include <libraries/reqtools.h>
  32. #include <libraries/locale.h>
  33. #include <intuition/intuitionbase.h>
  34. #include <workbench/startup.h>
  35. #include <clib/alib_protos.h>
  36.  
  37. #include <proto/exec.h>
  38. #include <proto/dos.h>
  39. #include <proto/graphics.h>
  40. #include <proto/commodities.h>
  41. #include <proto/icon.h>
  42. #include <proto/iffparse.h>
  43. #include <proto/intuition.h>
  44. #include <proto/layers.h>
  45. #include <proto/locale.h>
  46. #include <proto/reqtools.h>
  47. #include <proto/wb.h>
  48.  
  49. #include <string.h>
  50.  
  51. #include "Code.h"
  52. #include "yak.h"
  53. #include "hotkey_types.h"
  54. #include "beep.h"
  55. #include "Handlers.h"
  56. #include "icon.h"
  57. #include "version.h"
  58. #include "Requesters.h"
  59. #include "Settings.h"
  60. #include "Pri.h"
  61. #include "UnixDirs.h"
  62. #include "LastActiveWindow.h"
  63. #include "DigitalClock.h"
  64.  
  65. #define CATCOMP_BLOCK
  66. #define CATCOMP_NUMBERS
  67. #include "yak_locale_strings.h"
  68. #undef CATCOMP_BLOCK
  69.  
  70. #ifdef USE_WB2CLI
  71. #  include "WB2CLI.h"     /* we'll be a shell process */
  72. #endif
  73.  
  74. #define DEF_CURRENTDIR  "SYS:"
  75.  
  76. /* local prototypes for main.c */
  77. static void CloseResources(void);
  78. static BOOL OpenResources(void);
  79. static void FreePatterns(void);
  80. static LONG ProcessMsg(void);
  81. void MAIN(void);
  82.  
  83.  
  84. extern struct WBStartup *WBMsg;
  85. /*
  86.  *  libraries opened by startup code; basepointers needed by function pragmas
  87.  */
  88.  
  89. #if defined(_DCC)
  90.  
  91. extern struct ExecBase       *SysBase;
  92. extern struct DosLibrary     *DOSBase;
  93.  
  94. struct IntuitionBase  *IntuitionBase;
  95. struct GfxBase        *GfxBase;
  96.  
  97. /* global data - library bases and the like */
  98. struct Library  *CxBase, *IconBase,
  99.    *LayersBase,
  100.    *WorkbenchBase,
  101.    *IFFParseBase;
  102.  
  103. #endif
  104.  
  105. struct MsgPort *broker_mp;
  106. CxObj *broker;
  107. char *PopKeyStr;
  108. #define POPKEY_EVENT    1L      /* cannot clash with YHK event... */
  109.  
  110. char *PrefsPrg;
  111.  
  112.  
  113. struct NewBroker newbroker = {
  114.    NB_VERSION,
  115.    "Yak",                                              /* string to identify this broker */
  116.    VERSION_BROKER,
  117.    "Multi-purpose commodity",
  118.    NBU_UNIQUE | NBU_NOTIFY,    /* Don't want any new commodities
  119.                                 * starting with this name.  If someone
  120.                                 * tries it, let me know */
  121.    COF_SHOW_HIDE
  122.    };
  123.  
  124. ULONG           cxsigflag;
  125. ULONG           invariantsigflag = SIGBREAKF_CTRL_C;
  126. BYTE            palette_count;          /* how many palettes are open */
  127.  
  128.  
  129. /* close what we opened */
  130. static void
  131.    CloseResources()
  132. {
  133.    /* NULL pointers are valid so don't waste time to test them */
  134.    CloseLibrary((struct Library *)IntuitionBase);
  135.    CloseLibrary((struct Library *)GfxBase);
  136.    CloseLibrary(CxBase);
  137.    CloseLibrary(LayersBase);
  138.    CloseLibrary(IconBase);
  139.    CloseLibrary(WorkbenchBase);
  140.    CloseLibrary(IFFParseBase);
  141.    CloseLocaleStuff();
  142. }
  143.  
  144.  
  145.  
  146. /* open libraries, devices that we need */
  147. static BOOL
  148.    OpenResources(void)
  149. {
  150.    if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37L)) &&
  151.        (GfxBase       = (struct GfxBase *)OpenLibrary("graphics.library", 37L)) &&
  152.        (CxBase        = OpenLibrary("commodities.library", 37L)) &&
  153.        (LayersBase    = OpenLibrary("layers.library", 37L)) &&
  154.        (IconBase      = OpenLibrary("icon.library", 37L)) &&
  155.        (WorkbenchBase = OpenLibrary("workbench.library", 37L)) &&
  156.        (IFFParseBase  = OpenLibrary("iffparse.library", 37L)))
  157.    {
  158.       return TRUE;
  159.    }
  160.    CloseResources();
  161.    return FALSE;
  162. }
  163.  
  164.  
  165.  
  166. static void
  167.    FreePatterns()
  168. {
  169.    UWORD i;
  170.    
  171.    for (i = 0; i < NUM_PATTERNS; i++)
  172.       if (patterns[i].pat) FreeVec(patterns[i].pat);
  173. }
  174.  
  175.  
  176. BOOL
  177.    ShowYakInterface(void)
  178. {   
  179.    BPTR infh;
  180.    BPTR ppl;
  181.    
  182.    if (ppl=Lock(PrefsPrg, ACCESS_READ))
  183.    {
  184.       UnLock(ppl);
  185.       
  186.       if (infh=Open("Nil:", MODE_OLDFILE))
  187.       {
  188.          SystemTags(PrefsPrg, SYS_Input,  infh,
  189.                     SYS_Output, NULL,
  190.                     SYS_Asynch, TRUE,
  191.                     TAG_DONE);
  192.       }
  193.       
  194.       return TRUE;
  195.    }
  196.    
  197.    PostError("%s\n\"%s\"", getString(Launching_prefs_program_ERR), PrefsPrg);
  198.    return(FALSE);
  199. }
  200.  
  201.  
  202. static LONG notifysigbit;
  203. static ULONG notifysigflag;
  204. static struct NotifyRequest NotifyRequest;
  205.  
  206.  
  207. void
  208.    EndNotification(void)
  209. {
  210.    EndNotify(&NotifyRequest);
  211.    FreeSignal(notifysigbit);
  212. }
  213.  
  214. void
  215.    SetNotification(void)
  216. {
  217.    /* Allocate a signalsbit */
  218.    if ((notifysigbit = AllocSignal(-1L)) != -1)
  219.    {
  220.       notifysigflag = 1 << notifysigbit;
  221.       
  222.       /* Initialize notification request */
  223.       
  224.       NotifyRequest.nr_Name = ENV_CONFIG_FILE;
  225.       NotifyRequest.nr_Flags = NRF_SEND_SIGNAL; 
  226.       /* Signal this task */
  227.       NotifyRequest.nr_stuff.nr_Signal.nr_Task = (struct Task *) FindTask(NULL);
  228.       /* with this signals bit */
  229.       NotifyRequest.nr_stuff.nr_Signal.nr_SignalNum = notifysigbit;
  230.       
  231.       StartNotify(&NotifyRequest);
  232.    }
  233. }
  234.  
  235.  
  236. /* This function allows outside modules to register their signals */
  237.  
  238. void
  239.    RegisterSignal(ULONG I_sigflag)
  240. {
  241.    invariantsigflag |= I_sigflag;
  242. }
  243.  
  244.  
  245.  
  246. #ifdef _DCC
  247. void _waitwbmsg(void);
  248. static void
  249.    uncalled(void)
  250. {
  251.    _waitwbmsg();
  252. }
  253. #endif
  254.  
  255. UBYTE FRONT_DELAY, BACK_DELAY;
  256.  
  257. STRPTR ProgramName;
  258.  
  259. void MAIN()             /* Yak: multi-function commodity */
  260. {
  261.    BPTR newdir=NULL, olddir;
  262.    
  263.    if (OpenResources())
  264.    {
  265.       if (broker_mp = CreateMsgPort())
  266.       {
  267.          newbroker.nb_Port = broker_mp;
  268.          cxsigflag = 1L << broker_mp->mp_SigBit;
  269.          
  270.          if (WBMsg)             /* WB Startup */
  271.          {
  272.             struct WBArg *wbarg=&WBMsg->sm_ArgList[0];
  273.             
  274.             /* Get Program Name */
  275.             if (ProgramName=AllocVec(256, MEMF_CLEAR))
  276.             {
  277.                BPTR lock=GetProgramDir();
  278.                if (NameFromLock(lock, ProgramName, 256))
  279.                   AddPart(ProgramName, wbarg->wa_Name, 256);
  280.             }
  281.             
  282.             /* Current Directory */
  283.             if (newdir = Lock(DEF_CURRENTDIR, ACCESS_READ))
  284.                olddir = CurrentDir(newdir);
  285. #ifdef USE_WB2CLI
  286.             WB2CLI(WBMsg,4000,(struct DosLibrary *)DOSBase); /* get it over with... */
  287. #endif
  288.          }                        
  289.          else                   /* CLI Startup */
  290.          {
  291.             STRPTR TmpName;
  292.             
  293.             /* Get Program Name */
  294.             if ((ProgramName=AllocVec(256, MEMF_CLEAR)) &&
  295.                 (TmpName    =AllocVec(256, MEMF_CLEAR)))
  296.             {
  297.                BPTR lock=GetProgramDir();
  298.                
  299.                if (NameFromLock(lock, ProgramName, 256))
  300.                {
  301.                   int i;
  302.                   
  303.                   GetProgramName(TmpName, 256);
  304.                   
  305.                   /* when run in background program name 
  306.                    * includes part of program dir so keep
  307.                    * only the last part of it 
  308.                    */
  309.                   i = strlen(TmpName);
  310.                   while ((i>0) && (TmpName[i] != '/'))
  311.                   {
  312.                      i--;
  313.                   }
  314.                   if (TmpName[i] == '/')
  315.                   {
  316.                      i++;
  317.                   }
  318.                   AddPart(ProgramName, &TmpName[i], 256);
  319.                }
  320.             }
  321.          }
  322.          
  323.          /* process tool-types */
  324.          GetYakIcon(ProgramName);
  325.          
  326.          newbroker.nb_Pri = (BYTE)TTInt("CX_PRIORITY", 0);
  327.          
  328.          FRONT_DELAY=(UBYTE)TTInt("FRONT_DELAY", 6);
  329.          BACK_DELAY=(UBYTE)TTInt("BACK_DELAY", 6);
  330.          
  331.          if (broker = CxBroker(&newbroker, NULL))
  332.          {
  333.             /* HANDLER FIRST, SO IT SEES EVERYTHING!!! */
  334.             if (InitMainHandler())
  335.             {
  336.                InitYakHotKeyList();
  337.                
  338.                /* Open the right locale if tooltype LANGUAGE is used */
  339.                OpenLocaleStuff(TTString("LANGUAGE",NULL));
  340.                
  341.                PrefsPrg = DupStr(TTString("PREFSPRG", "Sys:Prefs/Yak"));
  342.                
  343.                if (PopKeyStr = DupStr(TTString("CX_POPKEY", "Rcommand help")))
  344.                {
  345.                   CxObj *tmpobj;
  346.                   
  347.                   if (tmpobj = HotKey(PopKeyStr, broker_mp, POPKEY_EVENT))
  348.                      AttachCxObj(broker, tmpobj);
  349.                   else
  350.                      PostError("%s:\"%s\"", getString(CX_POPKEY_invalid_ERR),
  351.                                PopKeyStr);
  352.                }
  353.                /* else... if this failed, we lose */
  354.                
  355.                MyPri(ACTIVE);
  356.                
  357.                LoadSettings(ENV_CONFIG_FILE);
  358.                
  359.                ActivateCxObj(broker, 1L);
  360.                
  361.                if (TTBool("CX_POPUP", FALSE) == TRUE)
  362.                   ShowYakInterface();
  363.                
  364.                if ((TTBool("APPICON", FALSE) == TRUE) &&
  365.                    (MakeYakAppIcon() == FALSE) &&
  366.                    (WBMsg != NULL))
  367.                {
  368.                   PostError(getString(Couldn_t_create_AppIcon_ERR));
  369.                }
  370.                
  371.                /* WB makes a copy of icon, so can free it */
  372.                FreeYakIcon();
  373.                
  374.                /*
  375.                 * We want to be notified each time either
  376.                 * ENV:yak.prefs is modified (by Yak Preferences)
  377.                 */
  378.                SetNotification();
  379.                
  380.                /* these are the signals waited for, + window sig */
  381.                invariantsigflag |= cxsigflag
  382.                   | clicksigflag | intuiopsigflag | blankscreensigflag
  383.                      | notifysigflag | depthscreensigflag;
  384.                
  385.                while (ProcessMsg())
  386.                   ;
  387.                RemoveAllAppIcons();
  388.                DeleteYakHotKeyList();
  389.                
  390.                FreeVec(PopKeyStr);
  391.                FreeVec(PrefsPrg);
  392.                MyPri(ORIGINAL);
  393.                
  394.                EndNotification();
  395.                EndMainHandler();
  396.                FreePatterns();
  397.                CleanMouseCycling();
  398.             }
  399.             else
  400.                PostError(getString(Allocation_ERR));
  401.             
  402.             DeleteCxObjAll(broker);
  403.          }
  404.          
  405.          if (newdir)
  406.          {
  407.             CurrentDir(olddir);
  408.             UnLock(newdir);
  409.          }
  410.          DeleteMsgPort(broker_mp);
  411.          
  412.          FreeYakIcon();         /* may already be gone, but so what? */
  413.          
  414.          if (ProgramName) FreeVec(ProgramName);
  415.       }
  416.       else PostError(getString(Allocation_ERR));
  417.       
  418.       ToggleUnixDirs( FALSE );
  419.       
  420.       DC_F_CleanUp();
  421.       
  422.       CloseResources();
  423.    }
  424.    else PostError(getString(Resource_ERR));
  425. }
  426.  
  427. IMPORT BYTE oldpri; /* priority before handlers.c changed it */
  428.  
  429. ULONG secs, micros;
  430.  
  431. /* monitor cx port, act on messages */
  432. static LONG
  433.    ProcessMsg(void)
  434. {
  435.    CxMsg *msg;
  436.    ULONG sigrcvd, msgid, msgtype;
  437.    struct InputEvent *ie;
  438.    LONG returnvalue = 1L;
  439.    
  440.    sigrcvd = Wait(invariantsigflag);
  441.    
  442.    if (sigrcvd & intuiopsigflag) 
  443.    {
  444.       /* intuiop requested */
  445.       intui_routine(intui_parameter); 
  446.    }
  447.    
  448.    DC_F_ProcessMsg(sigrcvd);
  449.    
  450.    if ((sigrcvd & clicksigflag) && click_volume) /* keyclick please */
  451.    {
  452.       beep(click_volume);
  453.    }
  454.    
  455.    if (sigrcvd & depthscreensigflag) /* screen depth gadget has been pressed */
  456.    {
  457.       ScreenDepthGadget();
  458.    }
  459.    
  460.    if (sigrcvd & blankscreensigflag) /* blank screen please */
  461.    {
  462.       BlankScreen();
  463.    }
  464.    
  465.    ProcessAppMsg(sigrcvd);
  466.    
  467.    if (sigrcvd & notifysigflag) /* settings have changed */
  468.    {
  469.       LoadSettings(ENV_CONFIG_FILE);
  470.    }
  471.    
  472.    while(msg = (CxMsg *)GetMsg(broker_mp))
  473.    {
  474.       msgid = CxMsgID(msg);
  475.       msgtype = CxMsgType(msg);
  476.       if(msgtype==CXM_IEVENT) 
  477.       {
  478.          /*
  479.           *  copy the interesting data of the inputevent
  480.           */
  481.          ie = (struct InputEvent *)CxMsgData(msg);
  482.          secs = ie->ie_TimeStamp.tv_secs;
  483.          micros = ie->ie_TimeStamp.tv_micro;
  484.       }
  485.       ReplyMsg((struct Message *)msg);
  486.       
  487.       switch(msgtype)
  488.       {
  489.       case CXM_IEVENT:
  490.          switch (msgid)
  491.          {
  492.             /* The msgid is used in 2 different ways:
  493.              * as a simple event number for both POPKEY_EVENT and mouse cycling events
  494.              * as a pointer to the structure of the hotkey to process
  495.              *
  496.              * This may look like a kludge but we can use safely small numbers for events
  497.              * because they will be out of adresses range. Low addresses are located in ROM.
  498.              */
  499.             
  500.          case POPKEY_EVENT:
  501.             ShowYakInterface();
  502.             break;
  503.             
  504.          case WINDOW_TOFRONT_EVENT:
  505.          case WINDOW_TOBACK_EVENT:
  506.          case SCREENCYCLING_EVENT:
  507.             /* Execute function attached to this event */
  508.             (*(MouseCyclingHandlers[msgid-WINDOW_TOFRONT_EVENT].HandlerFunction))();
  509.             break;
  510.             
  511.          default:
  512.             /* a generic hotkey... */
  513.             PerformAction((YakHotKey *)msgid);
  514.             break;
  515.             
  516.          }
  517.          break;
  518.          
  519.       case CXM_COMMAND:
  520.          switch(msgid)
  521.          {
  522.          case CXCMD_UNIQUE:
  523.          case CXCMD_APPEAR:
  524.             ShowYakInterface();
  525.             break;
  526.             
  527.          case CXCMD_DISAPPEAR:
  528.             BrokerCommand("Yak_Prefs", CXCMD_DISAPPEAR);
  529.             break;
  530.             
  531.          case CXCMD_DISABLE:
  532.             ActivateCxObj(broker, 0L);
  533.             TurnMouseOn();
  534.             DC_F_DisableClock();
  535.             break;
  536.             
  537.          case CXCMD_ENABLE:
  538.             ActivateCxObj(broker, 1L);
  539.             DC_F_EnableClock();
  540.             break;
  541.             
  542.          case CXCMD_KILL:
  543.             returnvalue = 0L;
  544.             break;
  545.          }
  546.          break;
  547.       }
  548.    }
  549.    
  550.    if (sigrcvd & SIGBREAKF_CTRL_C)
  551.       returnvalue = 0L;
  552.    
  553.    if (!returnvalue && !OkayToExit())
  554.    {
  555.       PostError(getString(Cannot_exit_palette_opened_ERR));
  556.       returnvalue = 1;
  557.    }
  558.    
  559.    return(returnvalue);
  560. }
  561.